home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -coverdisks- / af108a / ifx / prefs / ifx.e < prev    next >
Text File  |  1998-01-17  |  31KB  |  1,284 lines

  1. ->
  2. -> prefs.e
  3. ->
  4. -> An attempt at using GadTools to do the IFX preferences 
  5. -> program.
  6. ->
  7.  
  8. -> Modules
  9. MODULE 'dos',        'dos/dos',        'dos/dosextens',    'dos/dostags'
  10. MODULE 'asl',        'libraries/asl'
  11. MODULE 'intuition', 'intuition/intuition', 'intuition/gadgetclass',
  12.         'intuition/screens'
  13. MODULE 'graphics',  'graphics/text'
  14. MODULE 'gadtools',  'libraries/gadtools'
  15. MODULE 'exec/ports'
  16. MODULE 'utility/tagitem'
  17.  
  18. MODULE 'exec/obj/list',     'exec/obj/node'
  19. MODULE 'other/split'
  20. MODULE '*/modules/action',    '*/speak/speak'
  21. MODULE 'amigalib/tasks'
  22. MODULE 'tools/sound'
  23. MODULE 'fabio/rxobj_oo'
  24.  
  25. ->
  26. -> Object definitions
  27. ->
  28.  
  29.     -> ID
  30.     
  31. OBJECT ifx_id OF node
  32.     list    :PTR TO list        -> Action list
  33. ENDOBJECT
  34.  
  35.     -> Action
  36.  
  37. OBJECT ifx_action OF node
  38.     type        :PTR TO CHAR
  39. ENDOBJECT
  40.     
  41. -> Gadget ID's
  42. ENUM LV_IDS,
  43.      LV_ACTS,
  44.      BUT_DONE,
  45.      BUT_SAVE,
  46.      BUT_CANCEL,
  47.      BUT_ADDID,
  48.      BUT_REMID,
  49.      BUT_ADDACT,
  50.      BUT_REMACT,
  51.      BUT_OKAYID,
  52.      BUT_OKAYACT,
  53.      BUT_CANCELACT,
  54.      BUT_FILEREQ,
  55.      BUT_TESTACT,
  56.      BUT_EDITIDS,
  57.      STR_INFO,
  58.      STR_ID,
  59.      STR_DIR,
  60.      CY_TYPE,
  61.      ID_DUMMY
  62.  
  63.     -> Gadget objects
  64. DEF    lv_ids        :PTR TO gadget,
  65.     lv_acts        :PTR TO gadget,
  66.     but_save    :PTR TO gadget,
  67.     but_cancel    :PTR TO gadget,
  68.     but_done    :PTR TO gadget,
  69.     but_okayid    :PTR TO gadget,
  70.     but_addid    :PTR TO gadget,
  71.     but_remid    :PTR TO gadget,
  72.     but_addact    :PTR TO gadget,
  73.     but_remact    :PTR TO gadget,
  74.     but_filereq    :PTR TO gadget,
  75.     but_testact    :PTR TO gadget,
  76.     str_info    :PTR TO gadget,
  77.     str_id        :PTR TO gadget,
  78.     str_dir        :PTR TO gadget,
  79.     cy_type        :PTR TO gadget,
  80.     but_okayact    :PTR TO gadget
  81.     
  82. -> Global variables
  83.     -> Font
  84. DEF topaz80:PTR TO textattr
  85.  
  86.     -> Sounds
  87. DEF sounds:PTR TO LONG, curr
  88.  
  89.     -> Ids
  90. DEF ids:PTR TO list
  91.  
  92.     -> Port
  93. DEF g_mp:PTR TO mp
  94.     
  95.     -> Current ID and Action
  96. DEF id_curr:PTR TO ifx_id, act_curr:PTR TO ifx_action
  97.  
  98.     -> Last directory name
  99. DEF last_dir:PTR TO CHAR, def_dir:PTR TO CHAR
  100.  
  101.     -> ASL Requester
  102. DEF asl:PTR TO filerequester
  103.  
  104.     -> Directory locks
  105. DEF olddir, curdir
  106.  
  107. -> MAIN
  108. PROC main() HANDLE
  109.     DEF font
  110.     
  111.     -> First, find our current directory
  112.     olddir := CurrentDir(NIL)
  113.     
  114.     -> Allocate sounds space
  115.     NEW sounds[2]
  116.     
  117.     -> Create our ids list
  118.     NEW ids.init()
  119.     IF ids=NIL THEN Throw("MEM", ' (for IDS list)')
  120.     
  121.     -> Create our global message port
  122.     g_mp := CreateMsgPort()
  123.     IF g_mp=NIL THEN Throw("INIT", ' (message port)')
  124.     
  125.     -> Load the configuration
  126.     IF load_config() THEN put_error('Unable to open prefs file.\n')
  127.     
  128.     -> Open ASL
  129.     IF aslbase=NIL THEN aslbase := OpenLibrary('asl.library', 37)
  130.     IF aslbase=NIL /* Still */ THEN RETURN FALSE
  131.     
  132.     -> Open Gadtools
  133.     IF gadtoolsbase=NIL THEN gadtoolsbase := OpenLibrary('gadtools.library', 37)
  134.     IF gadtoolsbase=NIL /* Still */ THEN RETURN FALSE
  135.     
  136.     -> Open Datatypes
  137.     IF datatypesbase=NIL THEN datatypesbase := OpenLibrary('datatypes.library', 0)
  138.     
  139.     -> Initialize some stuff
  140.     topaz80 := ['topaz.font', 8, 0, 0]:textattr            -> Default font
  141.     
  142.     -> Create the ASL requester here!
  143.     asl := AllocAslRequest(ASL_FILEREQUEST,
  144.             [ASL_HAIL,            'Select A File',
  145.              NIL,                NIL])
  146.  
  147.     -> Open the font, to make sure it's possible
  148.     IF (font := OpenFont(topaz80))<>NIL
  149.         -> Do the stuff
  150.         dowindow({maingadgets})
  151.         
  152.         -> Close the font
  153.         CloseFont(font)
  154.     ELSE
  155.         put_error('Unable to open topaz font!\n')
  156.     ENDIF    
  157.  
  158.     IF asl THEN FreeAslRequest(asl)
  159.         
  160. EXCEPT DO
  161.     IF font            THEN CloseFont(font)
  162.     IF gadtoolsbase THEN CloseLibrary(gadtoolsbase)
  163.     gadtoolsbase := NIL
  164.     IF aslbase        THEN CloseLibrary(aslbase)
  165.     aslbase := NIL
  166.     IF datatypesbase THEN CloseLibrary(datatypesbase)
  167.     datatypesbase := NIL
  168.     IF olddir THEN CurrentDir(olddir)
  169.     IF curdir THEN UnLock(curdir)
  170. ENDPROC
  171.  
  172. PROC dowindow(makegadgets)
  173.     DEF myscr        :PTR TO screen,
  174.         mywin        :PTR TO window,
  175.         glist        :PTR TO gadget,
  176.         gad            :LONG,
  177.         userdata    :LONG,
  178.         done=0        :LONG,
  179.         vi            :LONG
  180.         
  181.  
  182.     -> Lock the public screen
  183.     IF (myscr := LockPubScreen(NIL))<>NIL
  184.         -> Get visual info
  185.         IF (vi := GetVisualInfoA(myscr, [TAG_END, NIL]))<>NIL
  186.             gad := makegadgets(myscr, vi, {glist})
  187.             IF gad
  188.                 -> Open the window
  189.                 IF (mywin := OpenWindowTagList(NIL,
  190.                         [WA_TITLE,        'IFX Preferences V2.00',
  191.                          WA_GADGETS,            glist,
  192.                          WA_AUTOADJUST,         TRUE,
  193.                          WA_WIDTH,                480,
  194.                          WA_INNERHEIGHT,        130,
  195.                          WA_DRAGBAR,            1,
  196.                          WA_CLOSEGADGET,        1,
  197.                          WA_DEPTHGADGET,        1,
  198.                          WA_ACTIVATE,            1,
  199.                          WA_SIMPLEREFRESH,        1,
  200.                          WA_IDCMP,            IDCMP_CLOSEWINDOW OR
  201.                                              IDCMP_REFRESHWINDOW OR
  202.                                              IDCMP_VANILLAKEY OR
  203.                                              LISTVIEWIDCMP OR
  204.                                              BUTTONIDCMP OR
  205.                                              STRINGIDCMP OR
  206.                                              CYCLEIDCMP,
  207.                          WA_PUBSCREEN,             myscr,
  208.                          NIL,                     NIL]))<>NIL
  209.                     
  210.                     -> Set userdata
  211.                     mywin.userdata := makegadgets
  212.  
  213.                     -> Refresh the gadgets
  214.                     Gt_RefreshWindow(mywin, NIL)
  215.                     
  216.                     WHILE done=NIL
  217.                         
  218.                         -> Do that gadget/message THANG..
  219.                         makegadgets := handlewindow(mywin, userdata)
  220.                         
  221.                         IF makegadgets
  222.                             -> Free up the old gadgets
  223.                             RemoveGList(mywin, glist, 0)
  224.                             FreeGadgets(glist)
  225.                             
  226.                             -> Make the new gadgets
  227.                             gad := makegadgets(myscr, vi, {glist})
  228.                             IF gad
  229.                                 -> Add the gadgets
  230.                                 AddGList( mywin, glist, -1, -1, NIL ) 
  231.                                 
  232.                                 -> Erase the old gadgets
  233.                                 EraseRect(mywin.rport, mywin.borderleft, mywin.bordertop, mywin.width-mywin.borderright-1, mywin.height-mywin.borderbottom-1)
  234.                                 
  235.                                 -> Draw the new ones
  236.                                 RefreshGadgets(glist, mywin, NIL)
  237.                                 
  238.                                 -> Refresh'em for fun!
  239.                                 Gt_RefreshWindow(mywin, NIL)
  240.                             ELSE
  241.                                 done := 1
  242.                             ENDIF
  243.                         ELSE
  244.                             done := 1
  245.                         ENDIF
  246.                     ENDWHILE
  247.                     
  248.                     -> Close the window
  249.                     CloseWindow(mywin)
  250.                  ELSE
  251.                      put_error('Unable to open window!\n')
  252.                  ENDIF
  253.             ELSE
  254.                 put_error('Unable to create gadgets!\n')
  255.             ENDIF
  256.                 FreeGadgets(glist)
  257.                 FreeVisualInfo(vi)
  258.         ELSE
  259.             put_error('Unable to get visual info!\n')
  260.             ENDIF
  261.             
  262.         UnlockPubScreen(NIL, myscr)
  263.     ELSE
  264.         put_error('Unable to lock public screen!\n')
  265.     ENDIF
  266. ENDPROC
  267.  
  268.  
  269. PROC handlewindow(win:PTR TO window, userdata)
  270.     DEF imsg:PTR TO intuimessage,
  271.         class, code, id, object, gad:PTR TO gadget,
  272.         ifx:PTR TO ifx_id, act:PTR TO ifx_action,
  273.         rx:PTR TO rxobj,
  274.         obj:PTR TO node,
  275.         thwin:PTR TO window,
  276.         temp:PTR TO CHAR,
  277.         done=NIL
  278.     
  279.  
  280.     WHILE done=NIL
  281.         WaitPort(win.userport)
  282.         WHILE (imsg := Gt_GetIMsg(win.userport))<>NIL
  283.             class  := imsg.class
  284.             code   := imsg.code
  285.             object := imsg.iaddress
  286.             thwin  := imsg.idcmpwindow
  287.             
  288.             SELECT class
  289.                 CASE IDCMP_REFRESHWINDOW
  290.                     -> Refresh the window and its gadgets
  291.                     Gt_BeginRefresh(thwin)
  292.                     Gt_EndRefresh(thwin, 1)
  293.                 
  294.                 CASE IDCMP_GADGETDOWN
  295.                 CASE IDCMP_MOUSEMOVE
  296.                 CASE IDCMP_GADGETUP
  297.                     gad := object
  298.                     id := gad.gadgetid
  299.                     
  300.                     gadgethit:
  301.                     
  302.                     SELECT id
  303.                         CASE LV_IDS
  304.                             IF lv_ids THEN killlist(lv_ids, win)
  305.                             id_curr := entrynum(ids, code)
  306.                             done := {idgadgets}
  307.                             
  308.                         CASE LV_ACTS
  309.                             IF id_curr
  310.                                 IF lv_acts THEN killlist(lv_acts, win)
  311.                                 act_curr := entrynum(id_curr.list, code)
  312.                                 done := {actgadgets}
  313.                             ENDIF
  314.                             
  315.                         CASE BUT_DONE
  316.                             done := {maingadgets}
  317.                                 
  318.                         CASE BUT_SAVE
  319.                             -> Save the config
  320.                             IF save_config()=-1 THEN put_error('Save failed!')
  321.                             
  322.                             -> Inform IFX
  323.                             NEW rx.rxobj('IFXPREFS')
  324.                             rx.send('PLAY', 'prefs', NIL, NIL)
  325.                             END rx
  326.                             done := -1
  327.                              
  328.                         CASE BUT_CANCEL
  329.                             IF ask('Are you sure you want\nto exit without saving?', win)
  330.                                 -> Yes
  331.                                 done := -1
  332.                             ELSE
  333.                                 -> No
  334.                             ENDIF    
  335.                         
  336.                         CASE BUT_OKAYID
  337.                             IF id_curr AND str_id
  338.                                 -> Read the new string
  339.                                 END id_curr.name
  340.                                 
  341.                                 obj := str_id.specialinfo::stringinfo.buffer
  342.                                 IF obj
  343.                                     NEW id_curr.name[StrLen(obj)+1]
  344.                                     StrCopy(id_curr.name, obj)
  345.                                 ENDIF
  346.                                 
  347.                                 -> Nullify the id
  348.                                 id_curr := NIL
  349.                             ELSE
  350.                                 put_error('DEBUG: Error @ 289')
  351.                             ENDIF
  352.                             done := {idsgadgets}
  353.  
  354.                         CASE BUT_ADDID
  355.                             killlist(lv_ids, win)
  356.                             id_curr := newid('new_id')
  357.                             IF id_curr
  358.                                 done := {idgadgets}
  359.                             ELSE
  360.                                 put_error('Unable to create new ID!')
  361.                             ENDIF
  362.                             
  363.                         CASE BUT_REMID
  364.                             IF id_curr
  365.                                 IF ask('Are you sure you want to\nremove this ID?', win)
  366.                                     -> Yes
  367.                                     END id_curr
  368.                                     id_curr := NIL
  369.                                     done := {idsgadgets}
  370.                                 ENDIF
  371.                             ELSE
  372.                                 put_error('DEBUG: Error 274')
  373.                             ENDIF
  374.                             
  375.                         CASE BUT_ADDACT
  376.                             IF id_curr
  377.                                 -> Clear old list (not destroy)
  378.                                 IF lv_ids THEN killlist(lv_ids, win)
  379.                                 
  380.                                 -> Create new action
  381.                                 NEW act_curr
  382.                                 IF act_curr
  383.                                     id_curr.list.addtail(act_curr)
  384.                                     done := {actgadgets}
  385.                                 ELSE
  386.                                     put_error('Unable to create new Action.\n')
  387.                                 ENDIF
  388.                             ELSE
  389.                                 put_error('DEBUG: Error 286')
  390.                             ENDIF
  391.                             
  392.                         CASE BUT_REMACT
  393.                             IF act_curr
  394.                                 act_curr.remove()
  395.                                 END act_curr
  396.                                 act_curr := NIL
  397.                                 done := {idgadgets}
  398.                             ENDIF
  399.                         
  400.                         CASE BUT_OKAYACT
  401.                             IF act_curr AND str_info
  402.                                 -> Read the new string
  403.                                 END act_curr.name
  404.                                 
  405.                                 obj := str_info.specialinfo::stringinfo.buffer
  406.                                 IF obj
  407.                                     NEW act_curr.name[(StrLen(obj)+1)]
  408.                                     IF act_curr.name
  409.                                         CopyMem(obj, act_curr.name, StrLen(obj)+1)
  410.                                     ENDIF
  411.                                 ENDIF
  412.                                 
  413.                                 -> Nullify the action
  414.                                 act_curr := NIL
  415.                                 -> Go back to the ID window
  416.                                 done := {idgadgets}
  417.                             ELSE
  418.                                 put_error('DEBUG: Error @ 330')
  419.                             ENDIF
  420.                         
  421.                         CASE BUT_FILEREQ
  422.                             -> If there is a string in the gadget, we'll
  423.                             -> use it for our drawer
  424.                             obj := str_info.specialinfo::stringinfo.buffer
  425.                             IF obj
  426.                                 IF StrLen(obj)>1
  427.                                     -> Allocate memory
  428.                                     NEW id[StrLen(obj)+2]
  429.                                     
  430.                                     -> Copy it
  431.                                     StrCopy(id, obj)
  432.                                     
  433.                                     -> Slash the file part
  434.                                     temp := PathPart(id)
  435.                                     temp[] := "\0"
  436.                                 ELSE
  437.                                     id := last_dir
  438.                                     temp := NIL
  439.                                 ENDIF
  440.                             ELSE
  441.                                 id := last_dir
  442.                                 temp := NIL
  443.                             ENDIF
  444.                             
  445.                             -> Create the request
  446.                                 
  447.                             -> If successful
  448.                             IF asl
  449.                                 IF AslRequest(asl,
  450.                                         [ASL_DIR,        IF id THEN id ELSE '',
  451.                                          ASL_FILE,      FilePart(str_info.specialinfo::stringinfo.buffer),
  452.                                          NIL, NIL])<>NIL
  453.                                     -> asl.drawer and asl.file are the strings
  454.                                     NEW temp[256]
  455.                                     IF temp
  456.                                         -> All names should relative to def_dir
  457.                                         CopyMem(def_dir, temp, StrLen(def_dir))
  458.                                         
  459.                                         -> Add all the strings together
  460.                                         IF AddPart(temp, asl.drawer, 256)
  461.                                         IF AddPart(temp, asl.file, 256)
  462.                                         -> Save dir for later use
  463.                                             IF asl.drawer
  464.                                                 END last_dir
  465.                                                 NEW last_dir[StrLen(asl.drawer)+1]
  466.                                                 IF last_dir
  467.                                                     StrCopy(last_dir, asl.drawer)
  468.                                                 ELSE
  469.                                                     put_error('Out of memory @ 443')
  470.                                                 ENDIF
  471.                                             ENDIF
  472.                                             
  473.                                             -> Set gadget, where we'll read it from later
  474.                                             Gt_SetGadgetAttrsA(str_info, win, NIL,
  475.                                                 [GTST_STRING,         temp,
  476.                                                  NIL,                NIL])
  477.                                                  
  478.                                         ENDIF
  479.                                         ENDIF
  480.                                         END temp
  481.                                     ELSE
  482.                                         put_error('Out of memory for string!')
  483.                                     ENDIF
  484.                                 ENDIF
  485.                             ENDIF
  486.                         
  487.                         CASE BUT_TESTACT
  488.                             IF lv_acts THEN killlist(lv_acts, win)
  489.                             IF act_curr
  490.                                 temp := str_info.specialinfo::stringinfo.buffer
  491.                                 IF temp
  492.                                     -> Destroy old
  493.                                     END act_curr.name
  494.                                     
  495.                                     -> Make new
  496.                                     NEW act_curr.name[StrLen(temp)+1]
  497.                                     IF act_curr.name
  498.                                         CopyMem(temp, act_curr.name, StrLen(temp)+1)
  499.                                         do_action(act_curr)
  500.                                     ELSE
  501.                                         put_error('Out of memory @ 446', win)
  502.                                         done := -1
  503.                                     ENDIF
  504.                                 ENDIF
  505.                             ENDIF
  506.                         
  507.                         CASE BUT_EDITIDS
  508.                             done := {idsgadgets}    
  509.                                 
  510.                         CASE CY_TYPE
  511.                             IF act_curr
  512.                                 SELECT code
  513.                                     CASE 0    -> "Sound"
  514.                                         act_curr.type := ACT_SOUNDFILE
  515.                                     CASE 1 -> "Preloaded Sound"
  516.                                         act_curr.type := ACT_SOUND
  517.                                     CASE 2 -> "Speech"
  518.                                         act_curr.type := ACT_SPEECH
  519.                                     CASE 3    -> "Executable"
  520.                                         act_curr.type := ACT_EXECUTE
  521.                                     CASE 4    -> "Other ID"
  522.                                         act_curr.type := ACT_IFX
  523.                                     CASE 5  -> "Nothing"
  524.                                         act_curr.type := ACT_NOTHING
  525.                                     CASE 6    -> "Exclude"
  526.                                         act_curr.type := ACT_DUMMY
  527.                                     CASE 7  -> "Message"
  528.                                         act_curr.type := ACT_REQUESTER
  529.                                 ENDSELECT
  530.                             ELSE
  531.                                 put_error('DEBUG: Error @ 337')
  532.                             ENDIF
  533.                             
  534.                         CASE STR_INFO
  535.                         CASE STR_ID
  536.                         CASE STR_DIR
  537.                             IF str_dir
  538.                                 IF curdir
  539.                                     CurrentDir(NIL)
  540.                                     UnLock(curdir)
  541.                                 ENDIF
  542.                                 curdir := Lock(str_dir.specialinfo::stringinfo.buffer, ACCESS_READ)
  543.                                 CurrentDir(curdir)
  544.                             ENDIF
  545.                         DEFAULT
  546.                             -> Unknown ID... ignore it!
  547.                     ENDSELECT
  548.                 
  549.                 CASE IDCMP_VANILLAKEY
  550.                     SELECT code
  551.                         CASE "n" -> New ID
  552.                             id := BUT_ADDID
  553.                         CASE "a" -> Add action
  554.                             id := BUT_ADDACT
  555.                         CASE "r" -> Remove ID
  556.                             id := BUT_REMID
  557.                         CASE "k" -> Keep ID
  558.                             id := BUT_OKAYID
  559.                         CASE "d" -> Delete Action
  560.                             id := BUT_REMACT
  561.                         CASE "s" -> Save
  562.                             id := BUT_SAVE
  563.                         CASE "c" -> Cancel Save
  564.                             id := BUT_CANCEL
  565.                         CASE "t"
  566.                             id := BUT_TESTACT
  567.                         DEFAULT
  568.                             id := NIL
  569.                     ENDSELECT
  570.                     IF id THEN JUMP gadgethit
  571.                     
  572.                 CASE IDCMP_CLOSEWINDOW
  573.                     IF ask('Do you really want\nto quit?  Your prefs\nwill not be saved!', win)
  574.                         done := -1
  575.                     ENDIF
  576.             ENDSELECT
  577.             
  578.             -> Loop to next message
  579.         ENDWHILE
  580.     ENDWHILE
  581.     
  582.     -> Set up the ID name when the screen goes off of it
  583.     IF id_curr AND (done = {actgadgets})
  584.         -> Read the new string
  585.         IF id_curr.name THEN END id_curr.name
  586.         
  587.         IF str_id
  588.             obj := str_id.specialinfo::stringinfo.buffer
  589.             IF obj
  590.                 NEW id_curr.name[StrLen(obj)+1]
  591.                 IF id_curr.name
  592.                     CopyMem(obj, id_curr.name, StrLen(obj)+1)
  593.                 ELSE
  594.                     put_error('Out of memory @ 517', win)
  595.                 ENDIF
  596.             ELSE
  597.                 put_error('Missing string @ 520', win)
  598.             ENDIF
  599.         ENDIF
  600.     ENDIF
  601.  
  602.     -> Check for total exit
  603.     IF done=-1 THEN RETURN NIL
  604.     
  605. ENDPROC done
  606.  
  607. PROC maingadgets(scr:PTR TO screen, vi, glistptr)
  608.     DEF ng:PTR TO newgadget,
  609.         gad:PTR TO gadget,
  610.         topborder
  611.         
  612.         -> Allocate the memory
  613.         NEW ng
  614.         
  615.         -> Get the top border size
  616.         topborder := scr.wbortop + scr.font.ysize + 4
  617.         
  618.         -> Create the context
  619.         gad := CreateContext(glistptr)
  620.         
  621.         -> Create the text gadget
  622.         ng.leftedge := scr.wborleft+2
  623.         ng.topedge  := topborder
  624.         ng.width    := 480-scr.wborleft-scr.wborright-2
  625.         ng.height    := 14
  626.         ng.gadgettext := 'IFX Preferences V2.1'
  627.         ng.textattr := topaz80
  628.         ng.gadgetid := NIL
  629.         ng.flags    := PLACETEXT_IN
  630.         ng.visualinfo := vi
  631.         ng.userdata := NIL            -> TODO
  632.         
  633.         gad := CreateGadgetA(TEXT_KIND, gad, ng,
  634.             [NIL,                NIL])
  635.         
  636.         -> Create next 5 line(s)
  637.         ng.topedge        := ng.topedge+ng.height
  638.         ng.gadgettext    := '© 1997 by Dobes Vandermeer'
  639.         gad := CreateGadgetA(TEXT_KIND, gad, ng, [NIL, NIL])
  640.         ng.topedge        := ng.topedge+ng.height
  641.         ng.gadgettext    := 'All rights reserved'
  642.         gad := CreateGadgetA(TEXT_KIND, gad, ng, [NIL, NIL])
  643.         ng.topedge        := ng.topedge+ng.height
  644.         ng.gadgettext    := ''
  645.         gad := CreateGadgetA(TEXT_KIND, gad, ng, [NIL, NIL])
  646.         
  647.         -> We'll put a button in the middle
  648.         ng.topedge        := ng.topedge+ng.height
  649.         ng.gadgettext    := 'Edit IDS'
  650.         ng.gadgetid        := BUT_EDITIDS
  651.         gad := CreateGadgetA(BUTTON_KIND, gad, ng, [NIL, NIL])
  652.         
  653.         ng.topedge        := ng.topedge+ng.height
  654.         ng.gadgettext    := ''
  655.         ng.gadgetid        := NIL
  656.         gad := CreateGadgetA(TEXT_KIND, gad, ng, [NIL, NIL])
  657.         
  658.         -> Create the string gadget
  659.         ng.topedge        := ng.topedge + ng.height + 5
  660.         ng.height        := 15
  661.         ng.flags        := PLACETEXT_ABOVE
  662.         ng.gadgettext    := 'Select default sounds/files directory:'
  663.         ng.gadgetid        := STR_DIR
  664.         
  665.         -> Get default directory string        
  666.         IF def_dir=NIL
  667.             NEW def_dir[256]
  668.             IF def_dir=NIL THEN Throw("MEM", ' (for default directory string)')
  669.         ENDIF
  670.         NameFromLock(curdir, def_dir, 256)
  671.         
  672.         -> Finish the job
  673.         str_dir := gad := CreateGadgetA(STRING_KIND, gad, ng,
  674.             [GTST_STRING,        def_dir,
  675.              GTST_MAXCHARS,        256,
  676.              NIL,                NIL])
  677.         
  678.         -> Create the "Cancel" button
  679.         ng.topedge    := ng.topedge + ng.height + 5
  680.         ng.leftedge := ng.leftedge + ng.width
  681.         ng.width    := (ng.width/2)-10
  682.         ng.leftedge := ng.leftedge - ng.width
  683.         ng.gadgettext := '_Cancel'
  684.         ng.gadgetid    := BUT_CANCEL
  685.         ng.flags    := NIL
  686.         ng.userdata := NIL            -> TODO
  687.         
  688.         but_cancel := gad := CreateGadgetA(BUTTON_KIND, gad, ng,
  689.                 [GT_UNDERSCORE,        "_",
  690.                  NIL,                NIL])
  691.  
  692.         -> Create the "Save" button
  693.         ng.leftedge := scr.wborleft+2
  694.         ng.gadgettext := '_Save'
  695.         ng.gadgetid := BUT_SAVE
  696.         ng.userdata := NIL            -> TODO
  697.         but_save := gad := CreateGadgetA(BUTTON_KIND, gad, ng,
  698.                 [GT_UNDERSCORE,        "_",
  699.                  NIL,                NIL])
  700. ENDPROC gad, NIL
  701.  
  702. PROC idsgadgets(scr:PTR TO screen, vi, glistptr)
  703.     DEF ng:PTR TO newgadget,
  704.         gad:PTR TO gadget,
  705.         topborder
  706.         
  707.         -> Allocate the memory
  708.         NEW ng
  709.         
  710.         -> Get the top border size
  711.         topborder := scr.wbortop + scr.font.ysize + 4
  712.         
  713.         -> Create the context
  714.         gad := CreateContext(glistptr)
  715.         
  716.         -> Create the listview gadget
  717.         ng.leftedge := scr.wborleft+2
  718.         ng.topedge  := topborder
  719.         ng.width    := 480-scr.wborleft-scr.wborright-2
  720.         ng.height    := 85
  721.         ng.gadgettext := ''
  722.         ng.textattr := topaz80
  723.         ng.gadgetid := LV_IDS
  724.         ng.flags    := NIL
  725.         ng.visualinfo := vi
  726.         ng.userdata := NIL            -> TODO
  727.         
  728.         lv_ids := gad := CreateGadgetA(LISTVIEW_KIND, gad, ng,
  729.             [GTLV_LABELS,        ids,
  730.              NIL,                NIL])
  731.              
  732.         -> Create the "Add" button
  733.         ng.topedge    := ng.topedge + ng.height + 5
  734.         ng.height    := 15
  735.         ng.gadgettext := '_New'
  736.         ng.gadgetid    := BUT_ADDID
  737.         ng.userdata := NIL            -> TODO
  738.         
  739.         but_addid := gad := CreateGadgetA(BUTTON_KIND, gad, ng,
  740.             [GT_UNDERSCORE,        "_",
  741.              NIL,                NIL])
  742.         
  743.         -> Create the "Done" button
  744.         ng.topedge    := ng.topedge + ng.height + 5
  745.         ng.gadgettext := 'Done'
  746.         ng.gadgetid   := BUT_DONE
  747.         
  748.         but_done := gad := CreateGadgetA(BUTTON_KIND, gad, ng,
  749.             [NIL, NIL])
  750.  
  751. ENDPROC gad, NIL
  752.  
  753. PROC idgadgets(scr:PTR TO screen, vi, glistptr)
  754.     DEF ng:PTR TO newgadget,
  755.         gad:PTR TO gadget,
  756.         topborder
  757.         
  758.         -> Allocate the memory
  759.         NEW ng
  760.         
  761.         -> Get the top border size
  762.         topborder := scr.wbortop + scr.font.ysize + 4
  763.         
  764.         -> Create the context
  765.         gad := CreateContext(glistptr)
  766.         
  767.         -> Create the listview gadget
  768.         ng.leftedge := scr.wborleft+2
  769.         ng.topedge  := topborder
  770.         ng.width    := 480-scr.wborleft-scr.wborright-2
  771.         ng.height    := 65
  772.         ng.gadgettext := ''
  773.         ng.textattr := topaz80
  774.         ng.gadgetid := LV_ACTS
  775.         ng.flags    := NIL
  776.         ng.visualinfo := vi
  777.         ng.userdata := id_curr
  778.         
  779.         lv_acts := gad := CreateGadgetA(LISTVIEW_KIND, gad, ng,
  780.             [GTLV_LABELS,        id_curr.list,
  781.              NIL,                NIL])
  782.         
  783.         -> Create the ID name entry string
  784.         ng.topedge        := ng.topedge + ng.height + 5
  785.         ng.height        := 15
  786.         ng.gadgetid        := STR_ID
  787.         str_id := gad := CreateGadgetA(STRING_KIND, gad, ng,
  788.             [GT_UNDERSCORE,            "_",
  789.              GTST_STRING,            id_curr.name,
  790.              GTST_MAXCHARS,            256,
  791.              NIL,                    NIL])
  792.      
  793.         -> Create the "Add" button
  794.         ng.topedge        := ng.topedge + ng.height + 5
  795.         ng.height        := 15
  796.         ng.gadgettext    := '_Add an Action'
  797.         ng.gadgetid        := BUT_ADDACT
  798.         
  799.         but_addact := gad := CreateGadgetA(BUTTON_KIND, gad, ng,
  800.             [GT_UNDERSCORE,        "_",
  801.              NIL,                NIL])
  802.         
  803.         -> Create the "OK" button
  804.         ng.topedge        := ng.topedge + ng.height + 5
  805.         ng.gadgettext    := '_Keep this'
  806.         ng.gadgetid        := BUT_OKAYID
  807.         ng.width        := (ng.width/3)
  808.         but_okayid := gad := CreateGadgetA(BUTTON_KIND, gad, ng,
  809.             [GT_UNDERSCORE,     "_",
  810.              NIL,                NIL])
  811.              
  812.         
  813.         -> Create the "Remove" Button
  814.         ng.gadgettext    := '_Remove This ID'
  815.         ng.gadgetid        := BUT_REMID
  816.         ng.leftedge        := ng.leftedge + (2*ng.width)
  817.         but_remid := gad := CreateGadgetA(BUTTON_KIND, gad, ng,
  818.             [GT_UNDERSCORE,        "_",
  819.              NIL,                NIL])
  820.         
  821. ENDPROC gad, lv_acts
  822.  
  823. PROC actgadgets(scr:PTR TO screen, vi, glistptr)
  824.     DEF ng:PTR TO newgadget,
  825.         gad:PTR TO gadget,
  826.         typenum,
  827.         topborder
  828.         
  829.         typenum := act_curr.type
  830.         SELECT typenum
  831.         CASE ACT_SOUNDFILE
  832.             typenum := 0
  833.         CASE ACT_SOUND
  834.             typenum := 1
  835.         CASE ACT_SPEECH
  836.             typenum := 2
  837.         CASE ACT_EXECUTE
  838.             typenum := 3
  839.         CASE ACT_IFX
  840.             typenum := 4
  841.         CASE ACT_NOTHING
  842.             typenum := 5
  843.         CASE ACT_DUMMY
  844.             typenum := 6
  845.         CASE ACT_REQUESTER
  846.             typenum := 7
  847.         DEFAULT
  848.             typenum := 5
  849.         ENDSELECT
  850.         
  851.         -> Allocate the memory
  852.         NEW ng
  853.         
  854.         -> Get the top border size
  855.         topborder := scr.wbortop + scr.font.ysize + 4
  856.         
  857.         -> Create the context
  858.         gad := CreateContext(glistptr)
  859.         
  860.         -> Create the cycle gadget
  861.         ng.leftedge := scr.wborleft+2
  862.         ng.topedge  := topborder
  863.         ng.width    := 480-scr.wborleft-scr.wborright-2
  864.         ng.height    := 15
  865.         ng.gadgettext := '_Type'
  866.         ng.textattr := topaz80
  867.         ng.gadgetid := CY_TYPE
  868.         ng.flags    := NIL
  869.         ng.visualinfo := vi
  870.         ng.userdata := act_curr            -> TODO
  871.         cy_type := gad := CreateGadgetA(CYCLE_KIND, gad, ng,
  872.             [GTCY_LABELS,        ['Sound', 'Preloaded Sound', 'Speech', 'Command', 'Other ID', 'Do Nothing', 'Task Exclusion', 'Requester Message',NIL],
  873.              GTCY_ACTIVE,        typenum,
  874.              NIL,                NIL])
  875.         
  876.         -> Create the string gadget
  877.         ng.topedge         := ng.topedge + 20
  878.         ng.gadgettext    := '_Info'
  879.         ng.gadgetid        := STR_INFO
  880.         str_info := gad := CreateGadgetA(STRING_KIND, gad, ng,
  881.             [GT_UNDERSCORE,            "_",
  882.              GTST_STRING,            act_curr.name,
  883.              GTST_MAXCHARS,            512,
  884.              NIL,                    NIL])
  885.         
  886.         -> Create the 'File...' gadget
  887.         ng.topedge         := ng.topedge + 20
  888.         ng.gadgettext    := '_File...'
  889.         ng.gadgetid        := BUT_FILEREQ
  890.         but_filereq := gad := CreateGadgetA(BUTTON_KIND, gad, ng, 
  891.             [GT_UNDERSCORE,            "_",
  892.              NIL,                    NIL])
  893.         
  894.         -> Create the "Okay" gadget
  895.         ng.topedge        := (ng.topedge * 2)+13
  896.         ng.width        := ng.width / 3
  897.         ng.gadgettext    := '_Okay'
  898.         ng.gadgetid        := BUT_OKAYACT
  899.         but_okayact := gad := CreateGadgetA(BUTTON_KIND, gad, ng,
  900.             [GT_UNDERSCORE,            "_",
  901.              NIL,                    NIL])
  902.         
  903.         -> Create the "Remove" gadget
  904.         ng.leftedge        := ng.leftedge + (2*ng.width)
  905.         ng.gadgettext    := '_Delete this Action'
  906.         ng.gadgetid        := BUT_REMACT
  907.         but_remact := gad := CreateGadgetA(BUTTON_KIND, gad, ng,
  908.             [GT_UNDERSCORE,            "_",
  909.              NIL,                    NIL])
  910.         
  911.         -> Create the "Test" gadget
  912.         ng.topedge        := ng.topedge - 40
  913.         ng.gadgettext    := 'Test'
  914.         ng.gadgetid        := BUT_TESTACT
  915.         but_testact := gad := CreateGadgetA(BUTTON_KIND, gad, ng,
  916.             [GT_UNDERSCORE,         "_",
  917.              NIL,                    NIL])
  918. ENDPROC gad
  919.  
  920.     ->
  921.     -> load_config()
  922.     ->
  923.     -> This is not compatible with the IFX code, because it loads
  924.     -> everything into a different type of list, and sets different
  925.     -> global variables.
  926.     ->
  927.  
  928. PROC load_config() HANDLE
  929.     DEF file, buf, temp:PTR TO CHAR, done=0, list:PTR TO LONG
  930.     DEF ifx:PTR TO ifx_id, action:PTR TO ifx_action
  931.     DEF type
  932.     
  933.     -> Open the file
  934.     file := Open('s:IFX.ids', MODE_OLDFILE)
  935.     IF file
  936.         NEW buf[1024]
  937.         IF buf
  938.             WHILE done=0
  939.                 -> Read a line
  940.                 IF Fgets(file, buf, 1024)=NIL THEN done:=1
  941.                 
  942.                 -> Set string to lower case
  943.                 LowerStr(buf)
  944.                 
  945.                 -> Split the line into pieces
  946.                 list := argSplit(buf)
  947.                 IF list=NIL THEN Throw("MEM", ' (for arg list)')
  948.                 
  949.                 ->
  950.                 -> All types MUST be longer then 3 chars, otherwise
  951.                 -> they will be considered comments
  952.                 ->
  953.                 IF StrLen(list[0])>3
  954.                 
  955.                     -> Find type
  956.                     type := NIL
  957.                     IF StrCmp(list[0], 'sound')   THEN type    := ACT_SOUNDFILE
  958.                     IF StrCmp(list[0], 'psound')  THEN type := ACT_SOUND
  959.                     IF StrCmp(list[0], 'speech')  THEN type := ACT_SPEECH
  960.                     IF StrCmp(list[0], 'exec')    THEN type    := ACT_EXECUTE
  961.                     IF StrCmp(list[0], 'other')   THEN type    := ACT_IFX
  962.                     IF StrCmp(list[0], 'exclude')
  963.                         type := ACT_DUMMY    
  964.                         list[2] := list[1]
  965.                         list[1] := 'Task Exclusions'
  966.                     ENDIF
  967.                     IF StrCmp(list[0], 'message') THEN type := ACT_REQUESTER
  968.                     IF StrCmp(list[0], 'defprefsdir')
  969.                         IF curdir
  970.                             IF olddir=NIL THEN olddir := CurrentDir(NIL)
  971.                             UnLock(curdir)
  972.                         ENDIF
  973.                         
  974.                         -> Get directory
  975.                         curdir := Lock(list[1], ACCESS_READ)
  976.                         
  977.                         -> Go there
  978.                         CurrentDir(curdir)
  979.                     ENDIF
  980.                     IF StrCmp(list[0], 'nothing') THEN type := -1
  981.                     
  982.                     IF type<>NIL
  983.                         -> Check if the ID already exists
  984.                         ifx := ids.findname(list[1])
  985.                         IF ifx=NIL THEN ifx := newid(list[1])
  986.                         
  987.                         -> Special case for type: ACT_NOTHING
  988.                         IF type=-1 THEN type := ACT_NOTHING        /* NIL */
  989.                         
  990.                         -> Add the entry
  991.                         IF list[2]
  992.                             -> Allocate the structure
  993.                             NEW action
  994.                             IF action=NIL THEN Throw("MEM", ' (for action data)')
  995.                             
  996.                             -> Get the data string
  997.                             NEW temp[StrLen(list[2])+1]
  998.                             IF temp=NIL THEN Throw("MEM", ' (for action string)')
  999.                             StringF(temp, '\s', list[2])
  1000.                             action.name         := temp
  1001.                             
  1002.                             -> Set the type
  1003.                             action.type            := type
  1004.                             
  1005.                             -> Add it to the list
  1006.                             ifx.list.addtail(action)
  1007.                         ENDIF
  1008.                     ENDIF
  1009.                 ENDIF
  1010.                 
  1011.                 -> Free the list
  1012.                 DisposeLink(list)
  1013.             ENDWHILE
  1014.             
  1015.             -> Free buffer
  1016.             END buf
  1017.         ELSE
  1018.             Throw("MEM", ' (for read buffer)')
  1019.         ENDIF
  1020.         Close(file)
  1021.     ELSE
  1022.         Throw("INIT", "LOAD")
  1023.     ENDIF
  1024. EXCEPT
  1025.     IF list THEN DisposeLink(list)
  1026.     IF file THEN Close(file)
  1027.     RETURN exception
  1028. ENDPROC
  1029.  
  1030. PROC save_config() HANDLE
  1031.     DEF file, buf:PTR TO CHAR, idname:PTR TO CHAR, actname:PTR TO CHAR
  1032.     DEF ifx:PTR TO ifx_id, act:PTR TO ifx_action
  1033.     DEF sel
  1034.     
  1035.     -> Error prevention
  1036.     IF ids=NIL THEN RETURN -1
  1037.     IF ids.is_empty() THEN RETURN NIL
  1038.     
  1039.     -> Open the file
  1040.     file := Open('s:IFX.ids', MODE_NEWFILE)
  1041.     IF file
  1042.         -> Allocate a write buffer
  1043.         NEW buf[1024]
  1044.         IF buf
  1045.             -> Write out our little header
  1046.             StringF(buf, '*\n* IFX.ids    generated by:\n* IFX Preferences\n* © 1997 by Dobes Vandermeer\n* (09.10.97)\n*\n')
  1047.             Fputs(file, buf)
  1048.             StringF(buf, '#\n## Default Directory (for everything)\n#\ndefprefsdir \s\n', def_dir)
  1049.             Fputs(file, buf)
  1050.             
  1051.             -> Loop through all the ids and write them out
  1052.             REPEAT
  1053.                 -> Go to head id
  1054.                 ifx := ids.head
  1055.                 IF ifx=NIL THEN RETURN NIL
  1056.                 
  1057.                 -> Set up name string
  1058.                 idname := ifx.name
  1059.                 
  1060.                 -> Write out a comment line
  1061.                 StringF(buf, '#\n## ID: "\s"\n#\n', idname)
  1062.                 Fputs(file, buf)
  1063.                 
  1064.                 -> Write out all the effects
  1065.                 WHILE ifx.list.is_empty()=NIL
  1066.                     act := ifx.list.head    -> Get head
  1067.                     IF act=NIL THEN RETURN NIL    -> Bad list
  1068.                     sel := act.type
  1069.                     SELECT sel
  1070.                         CASE ACT_SOUNDFILE
  1071.                             actname := 'SOUND'
  1072.                         CASE ACT_SOUND
  1073.                             actname := 'PSOUND'
  1074.                         CASE ACT_SPEECH
  1075.                             actname := 'SPEECH'
  1076.                         CASE ACT_EXECUTE
  1077.                             actname := 'EXEC'
  1078.                         CASE ACT_IFX
  1079.                             actname := 'OTHER'
  1080.                         CASE ACT_NOTHING
  1081.                             actname := 'NOTHING'
  1082.                         CASE ACT_DUMMY    -> Task Exclusion
  1083.                             actname := 'EXCLUDE'
  1084.                             idname  := act.name
  1085.                             act.name := 'This is ignored!'
  1086.                         CASE ACT_REQUESTER -> Message
  1087.                             actname := 'MESSAGE'
  1088.                         DEFAULT
  1089.                             actname := NIL
  1090.                     ENDSELECT
  1091.                     
  1092.                     IF actname AND idname
  1093.                         -> Write out the data
  1094.                         StringF(buf, '\s "\s" "\s"\n', actname, idname, act.name)
  1095.                         Fputs(file, buf)
  1096.                     ENDIF
  1097.                     
  1098.                     -> Remove and destroy the action
  1099.                     END act
  1100.                 ENDWHILE
  1101.                 
  1102.                 -> Remove and destroy the id
  1103.                 END ifx
  1104.             UNTIL ids.is_empty()
  1105.             
  1106.             -> Write out our little footer
  1107.             StringF(buf, '*\n* END IFX.ids (generated by IFX Preferences)\n')
  1108.             Fputs(file, buf)
  1109.         ENDIF
  1110.         Close(file)
  1111.     ELSE
  1112.         Throw("SAVE", "OPEN")
  1113.     ENDIF
  1114. EXCEPT
  1115.     IF file THEN Close(file)
  1116.     IF buf THEN END buf
  1117.     RETURN exception
  1118. ENDPROC
  1119.  
  1120. ->
  1121. -> ID functions
  1122. ->
  1123.  
  1124. PROC newid(id:PTR TO CHAR) HANDLE
  1125.     DEF ifx:PTR TO ifx_id
  1126.     DEF list:PTR TO list
  1127.     DEF temp:PTR TO CHAR
  1128.     
  1129.     -> Create the object
  1130.     NEW ifx
  1131.     IF ifx=NIL THEN Throw("MEM", ' (for new id)')
  1132.     
  1133.     NEW list.init()
  1134.     IF list=NIL THEN Throw("MEM", ' (for new ids list)')
  1135.     ifx.list := list
  1136.     
  1137.     -> Copy the ID
  1138.     NEW temp[StrLen(id)+1]
  1139.     IF temp
  1140.         StringF(temp, '\s', id)
  1141.         ifx.name := temp
  1142.         ids.addtail(ifx)
  1143.     ELSE
  1144.         Throw("MEM", ' (for id string)')
  1145.     ENDIF
  1146. EXCEPT
  1147.     IF ifx  THEN END ifx
  1148.     IF list THEN END list
  1149.     IF temp THEN END temp
  1150. ENDPROC ifx
  1151.  
  1152. ->
  1153. -> entrynum(l, n)
  1154. ->
  1155. -> Get entry "n" of the list "l"
  1156. ->
  1157.  
  1158. PROC entrynum(l:PTR TO list, num:LONG) IS l.entrynum(num)
  1159.  
  1160.     ->
  1161.     -> do_action(ext)
  1162.     ->
  1163.  
  1164. PROC do_action(action:PTR TO ifx_action, ext=NIL)
  1165.     DEF type, data, temp
  1166.     DEF snd:PTR TO sound, tsnd:PTR TO sound
  1167.     DEF rexx:PTR TO rxobj
  1168.     
  1169.     -> Crash prevention
  1170.     IF str_info=NIL THEN RETURN
  1171.     IF act_curr=NIL THEN RETURN
  1172.     
  1173.     -> Assign our useful values here
  1174. ->    data := action.name
  1175.     data := str_info.specialinfo::stringinfo.buffer
  1176.     type := action.type
  1177.     
  1178.     SELECT type
  1179.         CASE ACT_NOTHING
  1180.             /* DO NOTHING */
  1181.         CASE ACT_AREXX
  1182.             -> ext=command, data=host
  1183.             NEW rexx.rxobj('IFX_ACTION')
  1184.             rexx.send(data, ext, NIL, NIL)
  1185.             END rexx
  1186.                   
  1187.         CASE ACT_EXECUTE
  1188.             -> data=string
  1189.             temp := Open('NIL:', MODE_NEWFILE)
  1190.             SystemTagList(data, [SYS_INPUT,        temp, 
  1191.                                  SYS_OUTPUT,    temp,
  1192.                                  NIL,            NIL])
  1193.             Close(temp)
  1194.             
  1195.         CASE ACT_SOUND
  1196.             JUMP playsound
  1197.         
  1198.         CASE ACT_REQUESTER
  1199.             NEW temp[256]
  1200.             StringF(temp, 'Message for you:\n\s', data)
  1201.             put_message('IFX Message', temp)
  1202.             END temp
  1203.             
  1204.         CASE ACT_SOUNDFILE    
  1205.             playsound:
  1206.             NEW snd
  1207.             IF snd
  1208.                 IF snd.load(data)=NIL
  1209.                     -> If either of the sounds plays, we should wait for it
  1210.                     IF (snd.play(0)=NIL) OR (snd.play(1)=NIL)
  1211.                         Wait(snd.sigbits() OR SIGBREAKF_CTRL_C)
  1212.                     ENDIF
  1213.                 ENDIF
  1214.                 END snd
  1215.             ENDIF
  1216.             
  1217.         CASE ACT_IFX
  1218.             NEW temp[1024]
  1219.             StrCopy(temp, 'id ')
  1220.             StrAdd(temp, data)
  1221.             NEW rexx.rxobj('IFXPREFS_ACTION')
  1222.             rexx.send('PLAY', temp, NIL, NIL)
  1223.             END rexx      
  1224.             END temp
  1225.         
  1226.         CASE ACT_SPEECH
  1227.             say(data)
  1228.     ENDSELECT
  1229. ENDPROC
  1230.  
  1231. ->
  1232. -> put_error (str, win)
  1233. ->
  1234. -> output errors in an extensible way
  1235. ->
  1236.  
  1237. PROC put_error(str, win=NIL) IS EasyRequestArgs(win, 
  1238.                                 [SIZEOF easystruct, NIL, 'IFX Prefs Error', str, 'Okay'],
  1239.                                 NIL, NIL)
  1240.  
  1241. ->
  1242. -> put_message (str, win)
  1243. ->
  1244. -> output messages in an extensible way
  1245. ->
  1246.  
  1247. PROC put_message(title, str, win=NIL) IS EasyRequestArgs(win, 
  1248.                                 [SIZEOF easystruct, NIL, title, str, 'Okay'],
  1249.                                 NIL, NIL)
  1250. ->
  1251. -> ask(str, win)
  1252. ->
  1253. -> Ask user a yes or no question
  1254. ->
  1255.  
  1256. PROC ask(str, win=NIL) IS EasyRequestArgs(win,
  1257.                             [SIZEOF easystruct, NIL, 'IFX Preferences', str, 'Yes|No'],
  1258.                             NIL, NIL)
  1259.  
  1260. ->
  1261. -> Kill the listview's list
  1262. ->
  1263.  
  1264. PROC killlist(gad, win)
  1265.     IF gad THEN RETURN Gt_SetGadgetAttrsA(gad, win, NIL, [GTLV_LABELS, -1, NIL, NIL])
  1266. ENDPROC -1
  1267.  
  1268.     ->              <-
  1269.     -> ifx_#? PROCs <-
  1270.     ->              <-
  1271.  
  1272. PROC end() OF ifx_id
  1273.     self.remove()
  1274.     self.list.die()
  1275.     END self.list
  1276.     END self.name
  1277. ENDPROC
  1278.  
  1279.     ->
  1280.     -> Version string
  1281.     ->
  1282.     
  1283. vers: CHAR 0, '$VER: IFX Preferences 2.00', 0
  1284.